from .session import SessionHandler
import inspect


class APISessionHandler(SessionHandler):
    def initialize(self, api_package) -> None:
        self.api_package = api_package

    def async_process(self, api_path):
        args = {}
        for name, value in self.request.arguments.items():
            args[name] = self.get_argument(name) if len(value)==1 else self.get_arguments(name)
        for name, file in self.request.files.items():
            args[name] = file
        return self.call_api(api_path[0], args)

    def call_api(self, api_path, args):
        args['handler'] = self
        api_path = self.api_package + '.' + api_path.replace('/', '.')
        pos = api_path.rindex('.')
        package = api_path[:pos]
        pos += 1
        if pos < len(api_path) and api_path[pos] == '_':
            raise Exception('请勿调用私用函数' + api_path[pos:])

        exec('import ' + package)
        method = eval(api_path)
        argspec = inspect.getfullargspec(method)
        for arg in set(args) - set(argspec.args):
            del args[arg]
        for arg in args:
            value = args[arg]
            if value is not None and arg in argspec.annotations and type(value) == str:
                t = argspec.annotations[arg]
                if type(t) == type:
                    value = value.strip()
                    value = value.upper() in ('TRUE', 'YES', '1', 'ON') if t == bool else t(value)
                    args[arg] = value
        return method(**args)
